﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Log;

namespace LinuxSourcePkDownlader
{
    internal class KyGFBDesktopPkDownlader : PkDownladerAbs
    {
        protected readonly string _baseUrl = @"http://archive2.kylinos.cn/deb/kylin/production/PART-V10-SP1/custom/partner/V10-SP1/pool/all/";

        public KyGFBDesktopPkDownlader()
            : base("KyGFBDesktop")
        {

        }


        protected override void PrimitiveDownload(ThreadExPara threadPara, string dir)
        {
            using (HttpClient httpClient = base.CreateHttpClient())
            {
                Task<string> task;
                string htmlStr = null;

                Loger.Info("正在获取包列表");
                while (!threadPara.Token.IsCancellationRequested)
                {
                    try
                    {
                        task = httpClient.GetStringAsync(this._baseUrl);
                        htmlStr = task.Result;
                        break;
                    }
                    catch (AggregateException aex)
                    {
                        Loger.Warn(aex);
                        threadPara.WaitOne(1000);
                    }
                    catch (HttpRequestException hrex)
                    {
                        Loger.Warn(hrex);
                        threadPara.WaitOne(1000);
                    }
                }
                if (threadPara.Token.IsCancellationRequested)
                {
                    return;
                }

                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(htmlStr);
                //HtmlNode node = doc.DocumentNode.SelectSingleNode("/html/body/div[4]/div[1]/div[2]/ul[1]");
                var pkNodes = doc.DocumentNode.SelectNodes(@"//ul/li/a");
                Loger.Info($"获取分包表完成,共{pkNodes.Count}个包");
                int count = 0;

                Parallel.ForEach(pkNodes, (pkNode) =>
                {
                    try
                    {
                        if (threadPara.Token.IsCancellationRequested)
                        {
                            return;
                        }

                        var tmpCount = Interlocked.Increment(ref count);

                        string pkName = pkNode.GetAttributeValue("href", null);
                        if (string.IsNullOrWhiteSpace(pkName))
                        {
                            Loger.Info($"忽略{pkNode.InnerText},因为href为空");
                            return;
                        }

                        Loger.Info($"下载{tmpCount}/{pkNodes.Count}包\"{pkName}\"开始下载...");
                        //http://archive2.kylinos.cn/deb/kylin/production/PART-V10-SP1/custom/partner/V10-SP1/pool/all/360zip_1012_arm64.deb
                        string pkUrl = Path.Combine(this._baseUrl, pkName);

                        string pkFilePath;
                        if (pkName.EndsWith("amd64.deb", StringComparison.OrdinalIgnoreCase))
                        {
                            pkFilePath = PathEx.Combine(PathType.Local, dir, "amd64", pkName);
                        }
                        else if (pkName.EndsWith("arm64.deb", StringComparison.OrdinalIgnoreCase))
                        {
                            pkFilePath = PathEx.Combine(PathType.Local, dir, "arm64", pkName);
                        }
                        else if (pkName.EndsWith("loongarch64.deb", StringComparison.OrdinalIgnoreCase))
                        {
                            pkFilePath = PathEx.Combine(PathType.Local, dir, "loongarch64", pkName);
                        }
                        else if (pkName.EndsWith("mips64el.deb", StringComparison.OrdinalIgnoreCase))
                        {
                            pkFilePath = PathEx.Combine(PathType.Local, dir, "mips64el", pkName);
                        }
                        else
                        {
                            pkFilePath = PathEx.Combine(PathType.Local, dir, "all", pkName);
                        }

                        DirectoryInfoEx.CheckFilePathDirectory(pkFilePath);
                        if (File.Exists(pkFilePath))
                        {
                            Loger.Info($"下载{tmpCount}/{pkNodes.Count}包\"{pkName}\",忽略下载...");
                            return;
                        }

                        using (HttpClient httpClient2 = base.CreateHttpClient())
                        {
                            using (Stream stream = httpClient2.GetStreamAsync(pkUrl).Result)
                            {
                                using (var fs = File.Create(pkFilePath))
                                {
                                    stream.CopyTo(fs);
                                }
                            }
                        }
                        Loger.Info($"下载{tmpCount}/{pkNodes.Count}包\"{pkName}\"完成...");
                    }
                    catch (Exception ex)
                    {
                        Loger.Error(ex, $"");
                    }
                });

                Loger.Info("所有包下载完成...");

            }
        }



        protected override void Dispose(bool disposing)
        {

        }
    }
}
